<?php

namespace app\common\letterbusiness\user;

use app\common\mysql\user\PointLog as pointMysql;
use app\common\mysql\user\System as systemMysql;
use app\common\mysql\Users as userMysql;
use app\common\letterbusiness\user\UserMessage as userMessageBn;
use app\common\letterbusiness\user\UserLv as userLvBn;
use app\common\letterbusiness\User as userBn;

class Point extends \app\common\letterbusiness\AbstractModel {

    /**
     * 定义操作字符
     *
     * 详细说明
     * @形参 1为加，2为减
     * @访问      公有
     * @返回值    array
     * @throws
     */
    public static function Operationtype() {

        return array(
            '1' => "+",
            '2' => "-"
        );
    }

    /**
     * 抽奖列表
     *
     * */
    public static function adminlist($params) {
        self::_checkPageAndCount($params);
        $where = self::_getWhere($params);
        $params['query'] = self::_getQuery($params);
        $listdata = systemMysql::name('letter_point')
                ->where($where)
                ->paginate(array("list_rows" => $params['count'], false, 'query' => $params['query']));
        return $listdata;
    }

    /**
     * 获取Query条件
     *
     * @param array $params
     * @return array
     */
    protected static function _getQuery($params) {
        $query = array();
        if (isset($params['name'])) {
            $query['name'] = $params['name'];
        }
        if (isset($params['user_id'])) {
            $query['user_id'] = $params['user_id'];
        }
        if (isset($params['cat_id'])) {
            $query['cat_id'] = $params['cat_id'];
        }
        if (isset($params['country_type'])) {
            $query['country_type'] = $params['country_type'];
        }
        if (isset($params['is_delete'])) {
            $query['is_delete'] = $params['is_delete'];
        }
        return $query;
    }

    /**
     * 等级的对应表
     */
    public static function userLv() {
        return array(
            '1' => array('name' => '球小白', 'min' => 0, 'max' => 30, 'rank' => 1),
            '2' => array('name' => '看球客', 'min' => 31, 'max' => 100, 'rank' => 2),
            '3' => array('name' => '小球童', 'min' => 101, 'max' => 300, 'rank' => 3),
            '4' => array('name' => '小球迷', 'min' => 301, 'max' => 650, 'rank' => 4),
            '5' => array('name' => '玩球客', 'min' => 651, 'max' => 1200, 'rank' => 5),
            '6' => array('name' => '小球咖', 'min' => 1201, 'max' => 2000, 'rank' => 6),
            '7' => array('name' => '球老鸟', 'min' => 2001, 'max' => 3500, 'rank' => 7),
            '8' => array('name' => '老球探', 'min' => 3501, 'max' => 6000, 'rank' => 8),
            '9' => array('name' => '小球星', 'min' => 6001, 'max' => 12000, 'rank' => 9),
            '10' => array('name' => '超级球星', 'min' => 12001, 'max' => 30000, 'rank' => 10),
            '11' => array('name' => '金靴球王', 'min' => 30001, 'max' => 50000, 'rank' => 11),
            '12' => array('name' => '宇宙第一', 'min' => 50001, 'max' => 999999999, 'rank' => 12),
                //  '13' => array('name' => '球院博士后', 'min' => 50000, 'max' => 79999, 'rank' => 13),
                // '14' => array('name' => '球院硕导', 'min' => 80000, 'max' => 99999, 'rank' => 14),
                // '15' => array('name' => '球院博导', 'min' => 100000, 'max' => 999999999, 'rank' => 15),
        );
    }

    /**
     * 积分的获取和消耗
     * point_type 1.日常积分，2 任务积分，3积分消耗
     * source_type 1 签到,
     * */
    public static function pointSource($params = array()) {

        $datashow = systemMysql::name('letter_point')
                ->field("change_point,source_type,point_type,max,change_memo,change_lv_value")
                ->order("source_type asc")
                ->select();
        $datatemp = array();
        if ($datashow) {
            foreach ($datashow as $k => $v) {
                if (isset($params['point']) && $params['source_type'] == 1 && $params['point'] > 0) {
                    $v['change_point'] = $params['point'];
                }
                $datatemp[$v['source_type']]['point'] = $v['change_point'];
                $datatemp[$v['source_type']]['change_lv_value'] = $v['change_lv_value'];
                $datatemp[$v['source_type']]['max'] = $v['max'];
                $datatemp[$v['source_type']]['source_type'] = $v['source_type'];
                $datatemp[$v['source_type']]['point_type'] = $v['point_type'];

                $datatemp[$v['source_type']]['changemsg'] = array(
                    1 => array(
                        'change_point' => $v['change_point'],
                        'change_memo' => $v['change_memo'],
                        'source_type' => $v['source_type']),
                    2 => array(
                        'change_point' => $v['change_point'],
                        'change_memo' => $v['change_memo'],
                        'source_type' => $v['source_type']),
                );
            }
        }

        if (isset($datatemp[$params['source_type']]) && isset($params['source_type']) && !empty($params['source_type'])) {
            return $datatemp[$params['source_type']];
        }

        return array();
    }

    /**
     * 任务积分进入系统消息的类型
     * 意见反馈
     * 首次订阅
     * 第三方注册登录
     * 绑定手机号
     */
    public static function pointUserMessage() {
        return array(9, 13, 14, 15);
    }

    /**
     * 积分明细
     * @param array $params Description
     * page
     * count
     * need_total
     * user_id
     */
    public static function pointlist($params) {
        self::_checkPageAndCount($params);
        $where = Point::_getWhere($params);
        $listdata = pointMysql::name('letter_point_log')
                ->field("user_id,log_time,change_point,change_memo,change_type")
                ->where($where)
                ->order('log_time desc')
                ->limit($params['offset'], $params['count'])
                ->select();
        if (!empty($listdata)) {
            $listdata = self::_adapterList($listdata);
        }
        if (isset($params["need_total"]) && $params["need_total"] == 1) {
            return array("listdata" => $listdata, "total" => self::total($params));
        }
        return array("listdata" => (array) $listdata);
    }

    /**
     * 积分明细
     * @param array $params Description
     * page
     * count
     * need_total
     * user_id
     */
    public static function adminpointlist($params) {
        self::_checkPageAndCount($params);
        $where = Point::_getWhere($params);
        $params['query'] = self::_getQuery($params);
        $listdata = pointMysql::name('letter_point_log')
                ->field("user_id,log_time,change_point,change_memo,change_type")
                ->where($where)
                ->order('log_time desc')
                ->limit($params['offset'], $params['count'])
                ->paginate(array("list_rows" => $params['count'], false, 'query' => $params['query']));

        return $listdata;
    }

    /**
     * 适配输出
     *
     * @params
     * @return array
     */
    protected static function _adapterList($result) {
        return $result;
    }

    /**
     * 修改信息
     *
     * */
    public static function info($id) {

        return $data = pointMysql::name('letter_point')
                ->where('source_type=' . $id)
                ->find();
    }

    /**
     * 修改信息
     *
     * */
    public static function edit($post = array()) {
        $params = $post;
        return $data = pointMysql::name('letter_point')
                ->where('source_type=' . $post['source_type'])
                ->update($params);
    }

    /**
     * 添加
     *
     * */
    public static function add($post = array()) {
        return $data = pointMysql::name('letter_point')
                ->insert($post);
    }

    /**
     * 获取where条件
     *
     * @param array $params
     * @return array
     */
    protected static function _getWhere($params) {
        $where = array();
        if (isset($params["user_id"]) && !empty($params["user_id"])) {
            $where['user_id'] = $params["user_id"];
        }
        if (isset($params["start_time"]) && !empty($params["start_time"])) {
            $where['log_time>='] = $params["start_time"];
        }
        if (isset($params["end_time"]) && !empty($params["end_time"])) {
            $where['log_time<='] = $params["end_time"];
        }
        if (isset($params["change_type"]) && $params["change_type"] != '') {
            $where['change_type'] = $params["change_type"];
        }
        if (isset($params['point_type']) && !empty($params['point_type'])) {
            $where['point_type'] = $params['point_type'];
        }
        return $where;
    }

    /**
     * 计算总数
     *
     * @param array $params
     * @return int
     */
    public static function total($params) {
        $where = self::_getWhere($params);
        $count = pointMysql::name('letter_point_log')
                ->where($where)
                ->count();
        return $count;
    }

    /**
     *  我的积分
     */
    public static function mypoint($user_id) {
        $userinfo = userMysql::name('users')->find($user_id);
        return $userinfo['point'];
    }

    /**
     *  我的金球币
     */
    public static function mygoldball($user_id) {
        $userext_obj = new userextMysql();
        $userinfo = $userext_obj::name('user_ext')->where(array('user_id' => $user_id))->value('gold_ball');
        return $userinfo;
    }

    /**
     * 会员积分更新
     *
     * 详细说明
     * @形参
     * $user_id,
     * $change_point,
     * $change_type,  1为加，2为减 ,change_type 类型
     * $source_type   操作类型
     * $change_memo
     * $point_type
     * source_id
     * @访问      公有
     * @返回值    void
     * @throws
     *
     */
    public static function updatePoint($post, $is_tran = true) {
        $point = self::pointSource($post);
        //操作类型
        $user_id = $post['user_id'];
        if ($point) {
            //传积分值以以积分值为准
            $change_point = isset($post['change_point']) ? $post['change_point'] : $point['point'];
            $change_type = $post['change_type'];
            $change_memo = $point['changemsg'][$post['change_type']]['change_memo'];
            //首次订阅
            if ($point['changemsg'][$post['change_type']]['source_type'] == 15) {
                $memo = explode('-', $post['source_id']);
                $memostr = $point['changemsg'][$post['change_type']]['change_memo'];
                if ($memo[1] == 1) {
                    $memostr = $memostr . "足球";
                } elseif ($memo[1] == 2) {
                    $memostr = $memostr . "篮球";
                }

                $change_memo = $memostr;
            }
            $source_type = $point['changemsg'][$post['change_type']]['source_type'];
            $point_type = $point['point_type'];
        } else {
            $change_point = isset($post['change_point']) ? $post['change_point'] : $post['point'];
            $change_type = $post['change_type'];
            $change_memo = $post['change_memo'];
            $source_type = isset($post['source_type']) ? $post['source_type'] : 0;
            $point_type = isset($post['point_type']) ? $post['point_type'] : 0;
        }

        $operationtype = self::Operationtype()[$change_type];
        if (empty($operationtype)) {
            exception('格式有问题', 110039);
        }
        //积分日志字段
        $Request['user_id'] = $user_id;
        $Request['log_time'] = time();
        $Request['change_point'] = $change_point;
        $Request['change_type'] = $change_type;
        $Request['change_memo'] = $change_memo;
        $Request['source_type'] = $source_type;
        $Request['point_type'] = $point_type;
        $Request['source_id'] = isset($post['source_id']) ? $post['source_id'] : 0;
        // $require = self::pointSource($post['source_type'])['max'];
        // 有缓存不查数据库关闭
        $userext_obj = new userMysql();
        $userintegrallog = new pointMysql();
        $userinfo = userMysql::name('users')->find($user_id);
        try {
            //开始事务
            if ($is_tran == true) {
                $userext_obj::startTrans();
            }
            if (!empty($userinfo)) {
                //先查询次数是否超过了
                // if ($userintegrallog->SelectUserLog($Request, $require)) {
                //会员信息更新积分

                if ($userext_obj->UpdateUserIntegral($user_id, $change_point, $operationtype)) {

                    //如果是增加积分的时候记录等级
                    if ($operationtype === "+" && in_array($source_type, array(1, 2, 3, 4, 5, 6, 8, 9))) {
                        $lvdata = self::userLvOperation($Request);
                        if ($lvdata['lv_value'] > 0) {
                            $lvr = $userext_obj->UpdateUserLv($user_id, $lvdata['lv_value']);
                            if ($lvr != true) {
                                $userext_obj::rollback();
                                exception('更新等级失败', 104);
                            }
                        }
                    }

                    //插入日志
                    if (!$userintegrallog->AddUserIntegralLog($Request)) {
                        if ($is_tran === true) {
                            $userext_obj::rollback();
                        }
                        exception('插入积分日志失败', 110039);
                    }

                    if ($is_tran === true) {
                        $userext_obj::commit();
                    }

                    return true;
                } else {
                    if ($is_tran === true) {
                        $userext_obj::rollback();
                    }
                    exception('积分不足', 110040);
                }
                // }
            } else {
                //不存在进行插入
                $postg['user_id'] = $user_id;

                //会员信息更新积分
                if ($change_type == 1) {
                    $postg['point'] = intval($change_point);
                } elseif ($change_type == 2) {
                    $postg['point'] = 0;
                }
                if ($userext_obj->AddUserExt($postg)) {
                    //插入日志
                    if (!$userintegrallog->AddUserIntegralLog($Request)) {
                        if ($is_tran === true) {
                            $userext_obj->rollback();
                        }

                        exception('插入积分日志失败', 110039);
                    }
                    if ($is_tran === true) {
                        $userext_obj::commit();
                    }
                    return true;
                } else {
                    if ($is_tran === true) {
                        $userext_obj::rollback();
                    }
                    exception('更新积分失败', 110039);
                }
            }
        } catch (\Exception $e) {
            if ($is_tran == true) {
                $userext_obj::rollback();
            }
            exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 会员等级
     */
    public static function getUserrank($user_id) {
        $userext_obj = new userMysql();
        $userinfo = $userext_obj::name('users')->find($user_id);
        $lvdata = self::userLv();
        $data['lv'] = Point::getLevel($userinfo['lv'], $lvdata);
        $data['lv']['experience_to_next'] = 0;
        $data['pre_lv'] = Point::getPreLevel($userinfo['lv'], $lvdata);
        $data['next_lv'] = Point::getNextLevel($userinfo['lv'], $lvdata);
        if ($data['next_lv']) {
            $data['lv']['experience_to_next'] = $data['next_lv']['experience_to_next'];
        }
        return $data;
    }

    /**
     * 根据经验值取得上一个等级
     * @param type $experience
     * @return type
     */
    public static function getLevel($experience, $lvdata = '') {
        if (empty($lvdata)) {
            $lvdata = self::userLv();
        }
        //经验值为0时，返回下一等级返回LV2，避免返回LV1
        foreach ($lvdata as $k => $v) {
            if ($v['min'] <= $experience && $v['max'] >= $experience) {
                unset($v['max']);
                unset($v['min']);
                return $v;
            }
            if ($k == count($lvdata)) {
                unset($v['max']);
                unset($v['min']);
                return $v;
            }
        }
        unset($lvdata[1]['max']);
        unset($lvdata[1]['min']);
        return $lvdata[1];
    }

    /**
     * 根据经验值取得上一个等级
     * @param type $experience
     * @return type
     */
    public static function getPreLevel($experience, $lvdata) {
        //经验值为0时，返回下一等级返回LV2，避免返回LV1
        rsort($lvdata);
        foreach ($lvdata as $k => $v) {
            if ($v['max'] < $experience && $k >= 1) {
                unset($v['max']);
                unset($v['min']);
                return $v;
            } else {
                continue;
            }
        }
        return array();
    }

    /**
     * 根据经验值取得下一个等级
     * @param type $experience
     * @return type
     */
    public static function getNextLevel($experience, $lvdata) {
        //经验值为0时，返回下一等级返回LV2，避免返回LV1
        if ($experience == 0) {
            $lvdata[2]['experience_to_next'] = $lvdata[2]['min'] - $experience;
            unset($lvdata[2]['max']);
            unset($lvdata[2]['min']);
            return $lvdata[2];
        }

        foreach ($lvdata as $k => $v) {
            if ($v['min'] > $experience) {
                $v['experience_to_next'] = $v['min'] - $experience;
                unset($v['max']);
                unset($v['min']);
                return $v;
            }
        }
        return array();
    }

    /**
     * 当前用户积分，当前操作积分数
     * @param array $params Description
     * user_id
     * source_type
     * source_id
     * point
     */
    public static function pointOperation($parmas) {
        $data['point'] = 0;
        $pointSource = self::pointSource($parmas);

        if ($pointSource) {
            $data = $pointSource;
//            if ($pointSource['point_type'] == 1) {//日常积分
//                $data['point'] = self::dailyPoint($pointSource, $parmas['user_id']);
//            } elseif ($pointSource['point_type'] == 2) {//任务积分
//                $pointSource['source_id'] = isset($parmas['source_id']) ? $parmas['source_id'] : 0;
//                $data['point'] = self::taskPoint($pointSource, $parmas['user_id']);
//            } elseif ($pointSource['point_type'] == 3 && $pointSource['source_type'] == 16) {//消耗积分
//                if (isset($parmas['point'])) {
//                    $pointSource['point'] = $parmas['point'];
//                }
//                $pointSource['source_id'] = isset($parmas['source_id']) ? $parmas['source_id'] : 0;
//                $data['point'] = self::videoPoint($pointSource, $parmas['user_id']);
//            }
        }
        return $data;
    }

    /**
     * 当前用户等级，当前操作等级分数
     * @param array $params Description
     * user_id
     * source_type
     * source_id
     * point
     */
    public static function userLvOperation($parmas) {
        $data['lv_value'] = 0;
        $pointSource = self::pointSource($parmas);
        if ($pointSource) {
            $data = $pointSource;
            if ($pointSource['point_type'] == 1) {//日常 
                $data['lv_value'] = userLvBn::dailyLvValue($pointSource, $parmas['user_id']);
            } elseif ($pointSource['point_type'] == 2) {//任务 
                $pointSource['source_id'] = isset($parmas['source_id']) ? $parmas['source_id'] : 0;
                $data['lv_value'] = userLvBn::taskLv($pointSource, $parmas['user_id']);
            }
        }
        return $data;
    }

    /**
     * 当前用户日常的积分是否已满
     */
    public static function dailyPoint($parmas, $user_id) {
        $total = pointMysql::name('letter_point_log')->where(array(
                    'user_id' => $user_id,
                    'point_type' => $parmas['point_type'],
                    'source_type' => $parmas['source_type'],
                ))
                ->whereTime('log_time', 'today')
                ->sum('change_point');
        echo $total;
        if ($total >= $parmas['max']) {
            $parmas['point'] = 0;
        }
        return $parmas['point'];
    }

    /**
     * 当前任务积分是否已满
     */
    public static function taskPoint($parmas, $user_id) {
        $where['user_id'] = $user_id;
        $where['source_type'] = $parmas['source_type'];
        if (isset($parmas['source_id']) && !empty($parmas['source_id'])) {
            $where['source_id'] = $parmas['source_id'];
        }
        $total = pointMysql::name('letter_point_log')->where($where)
                ->sum('change_point');
        if ($parmas['max'] != 0 && $total >= $parmas['max']) {
            $parmas['point'] = 0;
        }
        return $parmas['point'];
    }

    /**
     * 当前视频是否要消耗积分
     * user_id
     * source_id
     * source_type
     */
    public static function videoPoint($parmas, $user_id) {
        $total = pointMysql::name('letter_point_log')->where(array(
                    'user_id' => $user_id,
                    'source_type' => $parmas['source_type'],
                    'source_id' => $parmas['source_id'],
                ))
                ->count();
        if ($total >= 1) {
            $parmas['point'] = 0;
        }
        return $parmas['point'];
    }

    /**
     * 积分的获取和消耗根据类型来更新积分
     * @param array $params
     * source_type
     * user_id
     * change_type
     * source_id
     * point
     */
    public static function updatePointBySource($params) {
        //日常操作积分
        $pointdata = self::pointOperation($params);
exit;
        //签到记录赠送积分
        if ($pointdata['point'] > 0) {
            $change['user_id'] = $params['user_id'];
            $change['change_point'] = isset($params['point']) ? $params['point'] : $pointdata['point'];
            if (isset($params['change_type'])) {
                $change['change_type'] = $params['change_type'];
            } else {
                $change['change_type'] = $pointdata['point_type'] == 3 ? 2 : 1;
            }
            if (isset($params['source_id']) && !empty($params['source_id'])) {
                $change['source_id'] = $params['source_id'];
            }
            $change['source_type'] = $params['source_type'];
            try {
                $r = self::updatePoint($change);
                //如果是任务积分的将推送信息到系统消息
                $addusermessage = self::pointUserMessage();
                if (in_array($pointdata['source_type'], $addusermessage)) {
                    $post['user_id'] = $change['user_id'];
                    $post['title'] = "任务积分获得通知";
                    $post['content'] = "主人，您成功通过【" . $pointdata['changemsg'][$change['change_type']]['change_memo'] . "】获得了【" . $change['change_point'] . "积分】！加油哦~更多积分在向您招手哦~";
                    $post['add_time'] = time();
                    $post['type'] = isset($pointdata['app_type']) ? $pointdata['app_type'] : 0;
                    $post['source_id'] = isset($pointdata['app_source_id']) ? $pointdata['app_source_id'] : "";
                    userMessageBn::addMessage($post);
                }
            } catch (\Exception $e) {
                $data['code'] = $e->getCode();
                $data['msg'] = $e->getMessage();
            }
        }
        $data['total_point'] = self::mypoint($params['user_id']);
        $data['point'] = isset($pointdata['point']) ? $pointdata['point'] : 0;
        return $data;
    }

    /**
     * 嗨豆兑换
     * user_id
     * money
     */
    public static function hdexchange($post) {
        //验证金豆够不够
        $total = userBn::checkMoney($post);
        if ($total <= 0) {
            exception('金豆不足', 110001);
        }
        userMysql::startTrans();
        try {
            $r2 = userBn::updateMoney(array('user_id' => $post['user_id'], 'money' => "-" . $post['money'], 'money_type' => 26, 'memo' => '嗨豆兑换'));
            if ($r2 != true) {
                exception('嗨豆兑换失败', 110001);
            }
            $change['user_id'] = $post['user_id'];
            $change['change_point'] = $post['money'] * 20;
            $change['change_type'] = 1;
            $change['source_type'] = 7;
            $change['change_memo'] = "嗨豆兑换";
            $change['point_type'] = 6;
            $r = self::updatePoint($change);
            if ($r != true) {
                exception('嗨豆兑换失败', 110001);
            }
            userMysql::commit();
            return true;
        } catch (\Exception $e) {
            userMysql::rollback();
            exception($e->getMessage(), 110001);
        }
    }

}
